package com.tanfuqi.sicent.server.router

import com.tanfuqi.sicent.server.handler.MemberHandler
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.server.*
import reactor.core.publisher.Mono
import reactor.core.publisher.toMono
import java.lang.RuntimeException
import java.util.*

//@Configuration
open class RouterRegistry {



    @Bean
    open fun monoRouterFunction(@Autowired memberHandler: MemberHandler): RouterFunction<ServerResponse> {
        return RouterFunctions.nest(RequestPredicates.path("/member"),
                RouterFunctions.route(RequestPredicates.method(HttpMethod.GET), HandlerFunction(memberHandler::get)).andNest(RequestPredicates.method(HttpMethod.POST), RouterFunctions.route(RequestPredicates.contentType(MediaType.APPLICATION_JSON), HandlerFunction(memberHandler::post))
                        .elseError(HttpStatus.METHOD_NOT_ALLOWED)
                ).elseError(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
        )


    }

}

fun <T : ServerResponse> route(predicate: RequestPredicate, handlerFunction: (serverRequset: ServerRequest) -> Mono<T>): RouterFunction<T> =
        RouterFunctions.route(predicate, HandlerFunction<T>(handlerFunction))

fun RouterFunction<ServerResponse>.`else`(handlerFunction: HandlerFunction<ServerResponse>): RouterFunction<ServerResponse> =
        this.and {
            handlerFunction.toMono()
        }

fun RouterFunction<ServerResponse>.`else`(handlerFunction: (serverRequset: ServerRequest) -> Mono<ServerResponse>): RouterFunction<ServerResponse> =
        this.`else`(HandlerFunction(handlerFunction))

fun RouterFunction<ServerResponse>.elseError(status: HttpStatus) =
        this.`else` {
            ServerResponse.status(status)
                    .body(Mono.empty())
        }


